home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_die_deliv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  16.4 KB  |  595 lines

  1. /*
  2.     dwarf_die_deliv.c
  3.  
  4.     This file implements section 5.2 of the Consumer API.
  5.     Essentially provides means of accessing Die's and
  6.     traversing the .debug_info section.  Also read section
  7.     7.5 of the Libdwarf document.
  8.  
  9.     $Revision: 1.37 $      $Date: 1994/06/17 02:39:13 $
  10. */
  11.  
  12. #include <libelf.h>
  13. #include <stdio.h>
  14. #include "dwarf_incl.h"
  15. #include "dwarf_die_deliv.h"
  16.  
  17.  
  18. /*
  19.     For a given Dwarf_Debug dbg, this function checks 
  20.     if a CU that includes the given offset has been read 
  21.     or not.  If yes, it returns the Dwarf_CU_Context 
  22.     for the CU.  Otherwise it returns NULL.  Being an 
  23.     internal routine, it is assumed that a valid dbg 
  24.     is passed.
  25.  
  26.     **This is a sequential search.  May be too slow.
  27. */
  28. static Dwarf_CU_Context
  29. _dwarf_find_CU_Context (
  30.     Dwarf_Debug        dbg,
  31.     Dwarf_Off        offset
  32. )
  33. {
  34.     Dwarf_CU_Context    cu_context;
  35.  
  36.     if (offset >= dbg->de_info_last_offset) 
  37.     return(NULL);
  38.  
  39.     if (dbg->de_cu_context != NULL && dbg->de_cu_context->cc_next != NULL &&
  40.     dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) 
  41.     return(dbg->de_cu_context->cc_next);
  42.  
  43.     for (cu_context = dbg->de_cu_context_list;
  44.     cu_context != NULL;
  45.     cu_context = cu_context->cc_next)
  46.  
  47.     if (offset >= cu_context->cc_debug_info_offset &&
  48.         offset < cu_context->cc_debug_info_offset + 
  49.         cu_context->cc_length + dbg->de_length_size)
  50.  
  51.         return(cu_context);
  52.     
  53.     return(NULL);
  54. }
  55.  
  56.  
  57. /*
  58.     This function is used to create a CU Context for
  59.     a compilation-unit that begins at offset in 
  60.     .debug_info.  The CU Context is attached to the
  61.     list of CU Contexts for this dbg.  It is assumed
  62.     that the CU at offset has not been read before,
  63.     and so do not call this routine before making
  64.     sure of this with _dwarf_find_CU_Context().
  65.     Returns NULL on error.  As always, being an
  66.     internal routine, assumes a good dbg.
  67. */
  68. static Dwarf_CU_Context
  69. _dwarf_make_CU_Context (
  70.     Dwarf_Debug        dbg,
  71.     Dwarf_Off        offset,
  72.     Dwarf_Error        *error
  73. )
  74. {
  75.     Dwarf_CU_Context    cu_context;
  76.     Dwarf_Unsigned    length;
  77.     Dwarf_Signed    abbrev_offset;
  78.     Dwarf_Byte_Ptr    cu_ptr;
  79.  
  80.     cu_context = (Dwarf_CU_Context)_dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
  81.     if (cu_context == NULL) {
  82.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  83.     return(NULL);
  84.     }
  85.     cu_context->cc_dbg = dbg;
  86.  
  87.     cu_ptr = (Dwarf_Byte_Ptr)(dbg->de_debug_info + offset);
  88.  
  89.     READ_UNALIGNED(length, cu_ptr, dbg->de_length_size);
  90.     cu_ptr += dbg->de_length_size;
  91.     cu_context->cc_length = length;
  92.  
  93.     READ_UNALIGNED(cu_context->cc_version_stamp, cu_ptr, sizeof(Dwarf_Half));
  94.     cu_ptr += sizeof(Dwarf_Half);
  95.  
  96.     READ_UNALIGNED(abbrev_offset, cu_ptr, dbg->de_length_size);
  97.     cu_ptr += dbg->de_length_size;
  98.     cu_context->cc_abbrev_offset = abbrev_offset;
  99.  
  100.     cu_context->cc_address_size = *(Dwarf_Small *)cu_ptr;
  101.  
  102.     if ((length < CU_VERSION_STAMP_SIZE + dbg->de_length_size + 
  103.     CU_ADDRESS_SIZE_SIZE) || 
  104.     (offset + length + dbg->de_length_size >
  105.     dbg->de_debug_info_size)) {
  106.     _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); 
  107.     return(NULL);
  108.     }
  109.  
  110.     if (cu_context->cc_address_size != dbg->de_length_size) {
  111.     _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD); 
  112.     return(NULL);
  113.     }
  114.  
  115.     if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP) {
  116.     _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 
  117.     return(NULL);
  118.     }
  119.  
  120.     if (abbrev_offset >= dbg->de_debug_abbrev_size) {
  121.     _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR); 
  122.     return(NULL);
  123.     }
  124.  
  125.     cu_context->cc_abbrev_hash_table = 
  126.     (Dwarf_Hash_Table)_dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
  127.     if (cu_context->cc_abbrev_hash_table == NULL) {
  128.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  129.     return(NULL);
  130.     }
  131.  
  132.     cu_context->cc_debug_info_offset = offset;
  133.     dbg->de_info_last_offset = offset + length + dbg->de_length_size;
  134.  
  135.     if (dbg->de_cu_context_list == NULL) {
  136.     dbg->de_cu_context_list = cu_context;
  137.     dbg->de_cu_context_list_end = cu_context;
  138.     }
  139.     else {
  140.     dbg->de_cu_context_list_end->cc_next = cu_context;
  141.     dbg->de_cu_context_list_end = cu_context;
  142.     }
  143.  
  144.     return(cu_context);
  145. }
  146.  
  147.  
  148. /*
  149.     Returns offset of next compilation-unit thru next_cu_offset
  150.     pointer.
  151.     It basically sequentially moves from one
  152.     cu to the next.  The current cu is recorded
  153.     internally by libdwarf.
  154. */
  155. int
  156. dwarf_next_cu_header (
  157.     Dwarf_Debug         dbg,
  158.     Dwarf_Unsigned      *cu_header_length,
  159.     Dwarf_Half          *version_stamp,
  160.     Dwarf_Unsigned      *abbrev_offset,
  161.     Dwarf_Half          *address_size,
  162.     Dwarf_Unsigned      *next_cu_offset,
  163.     Dwarf_Error         *error
  164. )
  165. {
  166.         /* Offset for current and new CU. */
  167.     Dwarf_Unsigned      new_offset;
  168.  
  169.     /* CU Context for current CU. */
  170.     Dwarf_CU_Context    cu_context;
  171.  
  172.     /* ***** BEGIN CODE ***** */
  173.  
  174.     if (dbg == NULL) {
  175.     _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
  176.     return(DW_DLV_ERROR);
  177.     }
  178.  
  179.     /* 
  180.         Get offset into .debug_info of next CU.
  181.         If dbg has no context, this has to be 
  182.         the first one.
  183.     */
  184.     if (dbg->de_cu_context == NULL) 
  185.     new_offset = 0;
  186.     else
  187.     new_offset = dbg->de_cu_context->cc_debug_info_offset +
  188.         dbg->de_cu_context->cc_length + dbg->de_length_size;
  189.  
  190.         /* 
  191.             Check that there is room in .debug_info beyond 
  192.             the new offset for at least a new cu header.
  193.         If not, return 0 to indicate end of debug_info
  194.         section, and reset de_cu_debug_info_offset to
  195.         enable looping back through the cu's.
  196.         */
  197.     if (new_offset + dbg->de_length_size + CU_VERSION_STAMP_SIZE +
  198.         dbg->de_length_size + CU_ADDRESS_SIZE_SIZE >= 
  199.         dbg->de_debug_info_size) {
  200.     dbg->de_cu_context = NULL;
  201.     return(DW_DLV_NO_ENTRY);
  202.     }
  203.  
  204.     /* Check if this CU has been read before. */
  205.     cu_context = _dwarf_find_CU_Context(dbg, new_offset);
  206.  
  207.     /* If not, make CU Context for it. */
  208.     if (cu_context == NULL)
  209.     cu_context = _dwarf_make_CU_Context(dbg, new_offset, error);
  210.  
  211.     /* Error if CU Context could not be made. */
  212.     if (cu_context == NULL) {
  213.     _dwarf_error(dbg, error, DW_DLE_MAKE_CU_CONTEXT_FAIL); 
  214.     return(DW_DLV_ERROR);
  215.     }
  216.  
  217.     dbg->de_cu_context = cu_context;
  218.  
  219.     if (cu_header_length != NULL)
  220.         *cu_header_length = cu_context->cc_length;
  221.  
  222.     if (version_stamp != NULL)
  223.         *version_stamp = cu_context->cc_version_stamp;
  224.  
  225.     if (abbrev_offset != NULL)
  226.         *abbrev_offset = cu_context->cc_abbrev_offset;
  227.  
  228.     if (address_size != NULL)
  229.         *address_size = cu_context->cc_address_size;
  230.  
  231.     new_offset = new_offset + cu_context->cc_length + dbg->de_length_size;
  232.     *next_cu_offset = new_offset;
  233.     return(DW_DLV_OK);
  234. }
  235.  
  236.  
  237. /* 
  238.     This function does two slightly different things
  239.     depending on the input flag want_AT_sibling.  If
  240.     this flag is true, it checks if the input die has
  241.     a DW_AT_sibling attribute.  If it does it returns
  242.     a pointer to the start of the sibling die in the
  243.     .debug_info section.  Otherwise it behaves the 
  244.     same as the want_AT_sibling false case.
  245.  
  246.     If the want_AT_sibling flag is false, it returns
  247.     a pointer to the immediately adjacent die in the 
  248.     .debug_info section.
  249.  
  250.     Die_info_end points to the end of the .debug_info 
  251.     portion for the cu the die belongs to.  It is used 
  252.     to check that the search for the next die does not 
  253.     cross the end of the current cu.  Cu_info_start points 
  254.     to the start of the .debug_info portion for the 
  255.     current cu, and is used to add to the offset for 
  256.     DW_AT_sibling attributes.  Finally, has_die_child 
  257.     is a pointer to a Dwarf_Bool that is set true if 
  258.     the present die has children, false otherwise.  
  259.     However, in case want_AT_child is true and the die 
  260.     has a DW_AT_sibling attribute *has_die_child is set 
  261.     false to indicate that the children are being skipped.
  262. */
  263. static Dwarf_Byte_Ptr
  264. _dwarf_next_die_info_ptr (
  265.     Dwarf_Byte_Ptr    die_info_ptr,
  266.     Dwarf_CU_Context    cu_context,
  267.     Dwarf_Byte_Ptr        die_info_end,
  268.     Dwarf_Byte_Ptr    cu_info_start,
  269.     Dwarf_Bool        want_AT_sibling,
  270.     Dwarf_Bool            *has_die_child
  271. )
  272. {
  273.     Dwarf_Byte_Ptr    info_ptr;
  274.     Dwarf_Byte_Ptr    abbrev_ptr;
  275.     Dwarf_Word        abbrev_code;
  276.     Dwarf_Abbrev_List    abbrev_list;
  277.     Dwarf_Half        attr;
  278.     Dwarf_Half        attr_form;
  279.     Dwarf_Unsigned    offset;
  280.     Dwarf_Word        leb128_length;
  281.  
  282.     info_ptr = die_info_ptr;
  283.     DECODE_LEB128_UWORD(info_ptr, abbrev_code)
  284.  
  285.     abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
  286.     if (abbrev_list == NULL)  {
  287.     return(NULL);
  288.     }
  289.  
  290.     *has_die_child = abbrev_list->ab_has_child;
  291.  
  292.     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
  293.     do {
  294.         DECODE_LEB128_UWORD(abbrev_ptr, attr)
  295.     DECODE_LEB128_UWORD(abbrev_ptr, attr_form)
  296.  
  297.     if (want_AT_sibling && attr == DW_AT_sibling) {
  298.         switch (attr_form) {
  299.             case DW_FORM_ref1 : 
  300.             offset = *(Dwarf_Small *)info_ptr; 
  301.             break;
  302.             case DW_FORM_ref2 :
  303.             READ_UNALIGNED(offset, info_ptr, sizeof(Dwarf_Half));
  304.             break;
  305.             case DW_FORM_ref4 :
  306.             READ_UNALIGNED(offset, info_ptr, sizeof(Dwarf_Word));
  307.             break;
  308.             case DW_FORM_ref8 : 
  309.             READ_UNALIGNED(offset, info_ptr, sizeof(Dwarf_Unsigned));
  310.             break;
  311.             case DW_FORM_ref_udata : 
  312.             offset = _dwarf_decode_u_leb128(info_ptr, &leb128_length);
  313.             break;
  314.             default : 
  315.             return(NULL);
  316.         }
  317.  
  318.         /* Reset *has_die_child to indicate children skipped.  */
  319.         *has_die_child = false;
  320.  
  321.         if (cu_info_start + offset > die_info_end)  {
  322.         return(NULL);
  323.         } else  {
  324.         return(cu_info_start + offset);
  325.         }
  326.         }
  327.  
  328.     if (attr_form != 0) {
  329.         info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg, 
  330.         attr_form, info_ptr);
  331.         if (info_ptr > die_info_end)  {
  332.         return(NULL);
  333.         }
  334.     }
  335.     } while (attr != 0 || attr_form != 0);
  336.  
  337.     return(info_ptr);
  338. }
  339.  
  340.  
  341. /*
  342.     Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns 
  343.     a Dwarf_Die for the sibling of die.  In case die is NULL, 
  344.     it returns (thru ptr) a Dwarf_Die for the first die in the current 
  345.     cu in dbg.  Returns DW_DLV_ERROR on error.
  346.  
  347.     It is assumed that every sibling chain including those with 
  348.     only one element is terminated with a NULL die, except a 
  349.     chain with only a NULL die.
  350.  
  351.     The algorithm moves from one die to the adjacent one.  It 
  352.     returns when the depth of children it sees equals the number 
  353.     of sibling chain terminations.  A single count, child_depth 
  354.     is used to track the depth of children and sibling terminations 
  355.     encountered.  Child_depth is incremented when a die has the 
  356.     Has-Child flag set unless the child happens to be a NULL die.  
  357.     Child_depth is decremented when a die has Has-Child false, 
  358.     and the adjacent die is NULL.  Algorithm returns when 
  359.     child_depth is 0.
  360.  
  361.     **NOTE: Do not modify input die, since it is used at the end.
  362. */
  363. int
  364. dwarf_siblingof (
  365.     Dwarf_Debug        dbg,
  366.     Dwarf_Die        die,
  367.     Dwarf_Die        *caller_ret_die,
  368.     Dwarf_Error        *error
  369. )
  370. {
  371.     Dwarf_Die        ret_die;
  372.     Dwarf_Byte_Ptr    die_info_ptr;
  373.     Dwarf_Byte_Ptr    cu_info_start;
  374.     Dwarf_Byte_Ptr    die_info_end;
  375.     Dwarf_Sword        child_depth;
  376.     Dwarf_Bool        has_child;
  377.     Dwarf_Half        abbrev_code;
  378.  
  379.  
  380.     if (dbg == NULL) {
  381.     _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 
  382.     return(DW_DLV_ERROR);
  383.     }
  384.  
  385.     if (die == NULL) {
  386.  
  387.         if (dbg->de_cu_context == NULL) {
  388.         _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT); 
  389.         return(DW_DLV_ERROR);
  390.     }
  391.  
  392.     die_info_ptr = dbg->de_debug_info +
  393.         dbg->de_cu_context->cc_debug_info_offset + dbg->de_length_size + 
  394.         CU_VERSION_STAMP_SIZE + dbg->de_length_size + 
  395.         CU_ADDRESS_SIZE_SIZE;
  396.  
  397.     }
  398.     else {
  399.  
  400.     CHECK_DIE(die, DW_DLV_ERROR)
  401.  
  402.     die_info_ptr = die->di_debug_info_ptr;
  403.     if (*die_info_ptr == 0)  {
  404.         return(DW_DLV_NO_ENTRY);
  405.     }
  406.     cu_info_start = dbg->de_debug_info + 
  407.         die->di_cu_context->cc_debug_info_offset;
  408.     die_info_end = cu_info_start + die->di_cu_context->cc_length + 
  409.         dbg->de_length_size;
  410.  
  411.     if ((*die_info_ptr) == 0) {
  412.         return(DW_DLV_NO_ENTRY);
  413.     }
  414.     child_depth = 0;
  415.         do {
  416.         die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr, 
  417.         die->di_cu_context, die_info_end, 
  418.         cu_info_start, true, &has_child);
  419.         if (die_info_ptr == NULL) {
  420.         _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); 
  421.         return(DW_DLV_ERROR);
  422.         }
  423.  
  424.         if ((*die_info_ptr) == 0 && has_child) {
  425.             die_info_ptr++;
  426.             has_child = false;
  427.         }
  428.  
  429.         if ((*die_info_ptr) == 0)
  430.         for ( ; child_depth > 0 && *die_info_ptr == 0; 
  431.             child_depth--, die_info_ptr++);
  432.         else
  433.         child_depth = has_child ? child_depth+1 : child_depth;
  434.  
  435.         } while (child_depth != 0);
  436.     }
  437.  
  438.     if (die != NULL && 
  439.     die_info_ptr >= cu_info_start + die->di_cu_context->cc_length){ 
  440.         return(DW_DLV_NO_ENTRY);
  441.     }
  442.  
  443.     if ((*die_info_ptr) == 0)  {
  444.     return(DW_DLV_NO_ENTRY);
  445.     }
  446.  
  447.     ret_die = (Dwarf_Die)_dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
  448.     if (ret_die == NULL) {
  449.     _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); 
  450.     return(DW_DLV_ERROR);
  451.     }
  452.  
  453.     ret_die->di_debug_info_ptr = die_info_ptr;
  454.     ret_die->di_cu_context = 
  455.     die == NULL ? dbg->de_cu_context : die->di_cu_context;
  456.  
  457.     DECODE_LEB128_UWORD(die_info_ptr, abbrev_code)
  458.     ret_die->di_abbrev_list = 
  459.     _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
  460.     if (ret_die->di_abbrev_list == NULL || (die == NULL && 
  461.     ret_die->di_abbrev_list->ab_tag != DW_TAG_compile_unit)) {
  462.         _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
  463.         return(DW_DLV_ERROR);
  464.     }
  465.  
  466.     *caller_ret_die = ret_die;
  467.     return(DW_DLV_OK);
  468. }
  469.  
  470.  
  471. int
  472. dwarf_child (
  473.     Dwarf_Die        die,
  474.     Dwarf_Die        *caller_ret_die,
  475.     Dwarf_Error        *error
  476. )
  477. {
  478.     Dwarf_Byte_Ptr    die_info_ptr;
  479.     Dwarf_Byte_Ptr    die_info_end;
  480.     Dwarf_Die        ret_die;
  481.     Dwarf_Bool        has_die_child;
  482.     Dwarf_Debug        dbg;
  483.     Dwarf_Half        abbrev_code;
  484.  
  485.  
  486.     CHECK_DIE(die, DW_DLV_ERROR)
  487.     dbg = die->di_cu_context->cc_dbg;
  488.     die_info_ptr = die->di_debug_info_ptr;
  489.  
  490.         /* NULL die has no child. */
  491.     if ((*die_info_ptr) == 0) 
  492.     return(DW_DLV_NO_ENTRY);
  493.  
  494.     die_info_end = dbg->de_debug_info + 
  495.     die->di_cu_context->cc_debug_info_offset + 
  496.     die->di_cu_context->cc_length + dbg->de_length_size;
  497.  
  498.     die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, 
  499.     die_info_end, NULL, false, &has_die_child);
  500.     if (die_info_ptr == NULL) {
  501.     _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); 
  502.     return(DW_DLV_ERROR);
  503.     }
  504.  
  505.     if (!has_die_child) return(DW_DLV_NO_ENTRY);
  506.  
  507.     ret_die = (Dwarf_Die)_dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
  508.     if (ret_die == NULL) {
  509.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  510.     return(DW_DLV_ERROR);
  511.     }
  512.     ret_die->di_debug_info_ptr = die_info_ptr;
  513.     ret_die->di_cu_context = die->di_cu_context;
  514.  
  515.     DECODE_LEB128_UWORD(die_info_ptr, abbrev_code)
  516.     ret_die->di_abbrev_list = 
  517.     _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
  518.     if (ret_die->di_abbrev_list == NULL) {
  519.     _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
  520.     return(DW_DLV_ERROR);
  521.     }
  522.  
  523.     *caller_ret_die = ret_die;
  524.     return(DW_DLV_OK);
  525. }
  526.  
  527.  
  528. int
  529. dwarf_offdie (
  530.     Dwarf_Debug        dbg,
  531.     Dwarf_Off        offset,
  532.     Dwarf_Die           *new_die,
  533.     Dwarf_Error        *error
  534. )
  535. {
  536.     Dwarf_CU_Context        cu_context;
  537.     Dwarf_Off            new_cu_offset = 0;
  538.     Dwarf_Die            die;
  539.     Dwarf_Byte_Ptr        info_ptr;
  540.     Dwarf_Half            abbrev_code;
  541.  
  542.     if (dbg == NULL) {
  543.     _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 
  544.     return(DW_DLV_ERROR);
  545.     }
  546.  
  547.     cu_context = _dwarf_find_CU_Context(dbg, offset);
  548.     if (cu_context == NULL) {
  549.  
  550.     if (dbg->de_cu_context_list_end != NULL)
  551.         new_cu_offset = 
  552.         dbg->de_cu_context_list_end->cc_debug_info_offset +
  553.         dbg->de_cu_context_list_end->cc_length + dbg->de_length_size;
  554.  
  555.     do {
  556.             if (new_cu_offset + dbg->de_length_size + CU_VERSION_STAMP_SIZE +
  557.                 dbg->de_length_size + CU_ADDRESS_SIZE_SIZE >= 
  558.                 dbg->de_debug_info_size) {
  559.         _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
  560.         return(DW_DLV_ERROR);
  561.         }
  562.  
  563.         cu_context = _dwarf_make_CU_Context(dbg, new_cu_offset, error);
  564.         if (cu_context == NULL) {
  565.         _dwarf_error(dbg, error, DW_DLE_MAKE_CU_CONTEXT_FAIL); 
  566.         return(DW_DLV_ERROR);
  567.         }
  568.  
  569.         new_cu_offset = new_cu_offset + cu_context->cc_length +
  570.         dbg->de_length_size;
  571.  
  572.     } while (offset >= new_cu_offset);
  573.     }
  574.  
  575.     die = (Dwarf_Die)_dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
  576.     if (die == NULL) {
  577.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  578.     return(DW_DLV_ERROR);
  579.     }
  580.     die->di_cu_context = cu_context;
  581.  
  582.     info_ptr = dbg->de_debug_info + offset;
  583.     die->di_debug_info_ptr = info_ptr;
  584.     DECODE_LEB128_UWORD(info_ptr, abbrev_code)
  585.  
  586.     die->di_abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
  587.     if (die->di_abbrev_list == NULL) {
  588.     _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
  589.     return(DW_DLV_ERROR);
  590.     }
  591.  
  592.     *new_die = die;
  593.     return(DW_DLV_OK);
  594. }
  595.